( function() {
	var $ = function(id) {
		if (typeof id == 'string') {
			return document.getElementById(id);
		}
		return id;
	};
	var ColorPicker = function(name) {
		this.name = name;
		this.showing = false;
	};

	ColorPicker.prototype.show = function() {
		var bindedObject = null;
		var localeString = null;
		if (arguments.length > 0) {
			bindedObject = $(arguments[0]);
		}
		if (arguments.length > 1) {
			localeString = arguments[1];
		}
		var e = getEvent();
		this.bindedObject = bindedObject || e.target || e.srcElement;
		this.localeString = (localeString || 'zh_cn').toLowerCase();
		this.generateHtml();
		this.init();
		this.setPosition();
		$(this.name + 'Container').style.display = 'block';
		stopBubble(e);
		this.showing = true;
	};

	ColorPicker.prototype.hide = function() {
		if (this.showing) {
			$(this.name + 'Container').style.display = 'none';
			this.showing = false;
		}
	};

	ColorPicker.prototype.init = function() {
		if (this.bindedObject.value) {
			this.selectColor(this.bindedObject.value);
		}
	};

	ColorPicker.prototype.generateHtml = function() {
		if (this.hasHtml) {
			return;
		}
		var baseColor = [ '00', '33', '66', '99', 'CC', 'FF' ];
		var curColor = '';
		var cpBody = '<table cellpadding="0" cellspacing="1"><tr>';
		cpBody += '<td id="' + this.name + 'colorPreview" colspan="9" class="colorPreview"></td>';
		cpBody += '<td colspan="6">#<input id="' + this.name + 'colorText" class="colorText" maxlength="6" value="000000" onkeyup="' + this.name + '.setColor(this.value);"></td>';
		cpBody += '<td colspan="3"><input type="button" class="button" value="ok" onclick="' + this.name + '.todo();"></td></tr>';
		cpBody += '<tr height="2px"><td colspan="18"> </td></tr>';
		for (var i = 0; i < 6; i++) {
			cpBody += '<tr>';
			for (var j = 0; j < 3; j++) {
				for (var k = 0; k < 6; k++) {
					curColor = baseColor[j] + baseColor[k] + baseColor[i];
					cpBody += '<td class="colorCell" onmouseover="' + this.name + '.selectColor(this.bgColor)" onclick="' + this.name + '.todo();" bgcolor="#' + curColor + '"></td>';
				}
			}
			cpBody += '</tr>';
		}
		for (i = 0; i < 6; i++) {
			cpBody += '<tr>';
			for (j = 3; j < 6; j++) {
				for (k = 0; k < 6; k++) {
					curColor = baseColor[j] + baseColor[k] + baseColor[i];
					cpBody += '<td class="colorCell" onmouseover="' + this.name + '.selectColor(this.bgColor)" onclick="' + this.name + '.todo();" bgcolor="#' + curColor + '"></td>';
				}
			}
			cpBody += '</tr>';
		}
		cpBody += '</table>';

		// For damn SELECT in IE6
		cpBody += '<iframe style="position:absolute;z-index:-1;width:100%;height:expression(this.parentNode.firstChild.offsetHeight);top:0;left:0;scrolling:no;" frameborder="0" src="about:blank"></iframe>';
		var cpDiv = document.createElement('div');
		cpDiv.className = 'colorPickerContainer';
		cpDiv.id = this.name + 'Container';
		cpDiv.innerHTML = cpBody;
		cpDiv.onclick = function() {
			stopBubble(getEvent());
		};
		cpDiv.onselectstart = cpDiv.onmousedown = cpDiv.oncontextmenu = function() {
			return false;
		};
		document.body.appendChild(cpDiv);
		this.hasHtml = true;
	};

	ColorPicker.prototype.setPosition = function(obj) {
		function getPosition(object) {
			var x = object.offsetLeft;
			var y = object.offsetTop;
			while (object && object.offsetParent) {
				x += object.offsetParent.offsetLeft;
				y += object.offsetParent.offsetTop;
				object = object.offsetParent;
			}
			return {
				x :x,
				y :y
			};
		}
		var xy = getPosition(this.bindedObject);
		$(this.name + 'Container').style.left = xy.x + 'px';
		$(this.name + 'Container').style.top = xy.y + this.bindedObject.offsetHeight + 2 + 'px';
	};

	ColorPicker.prototype.todo = function() {
		this.bindedObject.value = '#' + $(this.name + 'colorText').value;
		this.hide();
	};

	ColorPicker.prototype.setColor = function(colorvalue) {
		if ((/^[\da-fA-F]{6}/).test(colorvalue)) {
			$(this.name + 'colorPreview').style.backgroundColor = '#' + colorvalue;
		}
	};

	ColorPicker.prototype.selectColor = function(colorvalue) {
		$(this.name + 'colorText').value = colorvalue.substr(1).toUpperCase();
		$(this.name + 'colorPreview').style.backgroundColor = colorvalue;
	};
	
	document.write('<style type=\'text/css\'>');
	document.write('.colorPickerContainer{position:absolute; display:none; border: 1px solid #7B9EBD; padding:4px; background-color: #FFF; z-index: 99;}');
	document.write('.colorPickerContainer td{text-align: right;font-family:Arial;}');
	document.write('.colorPickerContainer .colorPreview{background-color: #000;}');
	document.write('.colorPickerContainer .colorText{width:52px;font-size:9pt;}');
	document.write('.colorPickerContainer .colorCell{height:12px; width:12px;}');
	document.write('.colorPickerContainer .button{height:20px;width:34px;border:1px solid #336699;}');
	document.write('</style>');
	
	var getEvent = function() {
		if (window.event) {
			return window.event;
		}
		var func = getEvent.caller;
		while (func !== null) {
			var arg0 = func.arguments[0];
			if (arg0 && (arg0.constructor == Event || arg0.constructor == MouseEvent)) {
				return arg0;
			}
			func = func.caller;
		}
		return null;
	};
	var stopBubble = function(e) {
		if (e && e.stopPropagation) {
			e.stopPropagation();
		} else {
			window.event.cancelBubble = true;
		}
	};
	var domReady = function(fn) {
		if (domReady.done) {
			return fn();
		}
		if (domReady.timer) {
			domReady.ready.push(fn);
		} else {
			addEvent(window, 'load', isDOMReady);
			domReady.ready = [ fn ];
			domReady.timer = setInterval(isDOMReady, 13);
		}
	};
	var isDOMReady = function() {
		if (domReady.done) {
			return false;
		}
		if (document && document.getElementsByTagName && $ && document.body) {
			clearInterval(domReady.timer);
			domReady.timer = null;
			for ( var i = 0; i < domReady.ready.length; i++) {
				domReady.ready[i]();
			}
			domReady.ready = null;
			domReady.done = true;
		}
	};
	var addEvent = function(element, type, fn) {
		if (element.addEventListener) {
			element.addEventListener(type, fn, false);
		} else {
			if (element.attachEvent) {
				element['e' + type + fn] = fn;
				element[type + fn] = function() {
					element['e' + type + fn](window.event);
				};
				element.attachEvent('on' + type, element[type + fn]);
			}
		}
	};
	domReady( function() {
		var colorpicker = window.colorpicker = new ColorPicker('colorpicker');
		addEvent(document, 'click', function() {
			colorpicker.hide();
		});
	});
})();
